feat: allow conversational agents to optionally end exchange [JAR-9933]#127
feat: allow conversational agents to optionally end exchange [JAR-9933]#127andrewwan-uipath wants to merge 5 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds support for leaving CAS exchanges open after a successful conversational run by introducing an end_exchange flag, while preserving the existing default behavior (emit exchange-end).
Changes:
- Add
end_exchange: bool = TruetoUiPathChatRuntimeand conditionally emit the exchange-end event only when enabled. - Map
fpsProperties["conversationalService.endExchange"]ontoUiPathRuntimeContext.end_exchangewith a default ofTrue. - Add unit tests for the new mapping and for default/explicit
end_exchangebehavior; bump package version to0.12.0.
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| uv.lock | Updates lock metadata and reflects version bump. |
| pyproject.toml | Bumps package version to 0.12.0. |
| src/uipath/runtime/context.py | Adds end_exchange to context and maps CAS fpsProperty to it. |
| src/uipath/runtime/chat/runtime.py | Adds end_exchange option and guards exchange-end event emission. |
| tests/test_context.py | Adds tests verifying fpsProperty mapping and default behavior for end_exchange. |
| tests/test_chat.py | Adds tests covering default, explicit True, and False behavior for exchange-end emission. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| self, | ||
| delegate: UiPathRuntimeProtocol, | ||
| chat_bridge: UiPathChatProtocol, | ||
| end_exchange: bool = True, |
There was a problem hiding this comment.
I wouldn't add this here - the event needs to be emitted, whether you honor it or not, that should be in the bridge implementation
There was a problem hiding this comment.
@andrewwan-uipath uipath-runtime is a very low-level abstraction. CAS/Maestro-specific logic belongs in the implementation layer - it shouldn't be pushed down into the underlying abstractions.
There was a problem hiding this comment.
Makes sense, I will move this to the implementation layer
There was a problem hiding this comment.
@cristipufu [Not-blocking] But wanted to ask:
My intuition was leaning towards the original approach Andrew had as well; can you elaborate on what you mean by "the exchange-event needs to be emitted" always? To me, emit_exchange_end_event() is already CAS specific - its a CAS-defined event that says "emit the event that marks the end of the current turn/exchange".
This new feature is to ensure the agent-runtime doesn't always end the exchange (so downstream agents/messages that have more messages to add can end the exchange themselves). This means that for Flow, we can call a conversational agent without having it emit end-exchange event, so that the chat-UI still shows "responding..." rather than that the turn was over.
so my intuition is saying to use the original approach where the runtime-layer doesn't call the emit_exchange_end_event function depending on if a flag is passed-in. Also was thinking it could avoid the weirdness that the function called emit_exchange_end_event but the bridge-implementation doesn't actually send the event conditionally.
There was a problem hiding this comment.
Right now the runtime's event contract changes based on a constructor arg, sometimes it ends the exchange, sometimes it doesn't, so you can't reason about what events come out of the runtime without knowing how it was built. The "don't end the turn so the UI keeps showing responding…" logic is pure CAS/Flow orchestration concern, and we're pushing it down into a low-level abstraction that shouldn't know Flow exists.
The runtime calling emit_exchange_end_event() unconditionally and the bridge deciding what that means isn't weird, it's the layering working: runtime reports "my turn is done," bridge owns the CAS semantics of whether that translates to a terminal event on the wire. If Flow wants to suppress it, the bridge is the thing that knows that. The runtime doesn't.
So same outcome you want, Flow can keep the exchange open, just with the branch living in the layer that already owns the CAS protocol rather than as a flag on the generic runtime.
There was a problem hiding this comment.
Sounds good, thank you @cristipufu ! I guess its more of a naming thing then - emit_exchange_end_event should probably be changed to emit_turn_complete_event but its not a big issue and totally okay in my opinion.
I'm good to get this method (extracted to bridge layer) merged.
| [project] | ||
| name = "uipath-runtime" | ||
| version = "0.11.0" | ||
| version = "0.12.0" |
There was a problem hiding this comment.
I think we can get away with a patch increase to avoid incrementing the ranges in all the repos
…ally-end-exchange
|



Uh oh!
There was an error while loading. Please reload this page.